Description

In this notebook an integrated analysis is preformed. Pair interaction data of miR - target(mRNA) and DNAm - target(mRNA) is an output from notebook 02-Regulation_targets. Integrative analysis is goint go be focused on mRNA so a table with significantly DE and one of its regulator. Since there are some genes that have multiple regulators mir’s with the best correlation will be selected as a regulator. For DNAm !!! get back to this To explore the influence of miR and DNAm on mRNA expression we will preform GSEA on groups of genes that are under regulation of DNAm, mir or both. Next, we will make an unsupervised clustering on genes with FC features to find patterns in gene expressions. (OVO ISTO POBOLJŠATI)

Libraries

library(venn)
library(dplyr)

Attaching package: ‘dplyr’

The following object is masked from ‘package:Biobase’:

    combine

The following object is masked from ‘package:matrixStats’:

    count

The following objects are masked from ‘package:GenomicRanges’:

    intersect, setdiff, union

The following object is masked from ‘package:GenomeInfoDb’:

    intersect

The following objects are masked from ‘package:IRanges’:

    collapse, desc, intersect, setdiff, slice,
    union

The following objects are masked from ‘package:S4Vectors’:

    first, intersect, rename, setdiff,
    setequal, union

The following objects are masked from ‘package:BiocGenerics’:

    combine, intersect, setdiff, union

The following objects are masked from ‘package:stats’:

    filter, lag

The following objects are masked from ‘package:base’:

    intersect, setdiff, setequal, union
library(GenomicRanges)
library(gprofiler2)
Registered S3 method overwritten by 'data.table':
  method           from
  print.data.table     
Registered S3 method overwritten by 'htmlwidgets':
  method           from         
  print.htmlwidget tools:rstudio
library(DESeq2)
library(tibble)
library(kohonen)
library(rprojroot)



# source(file = file.path(getwd(), "scripts", "idMap.R"))
# source(file = file.path(getwd(), "scripts", "integrateOmicsData.R"))
# source(file = file.path(getwd(), "scripts", "kmeansHeatmap.R"))

genes_dir <- file.path(find_rstudio_root_file(), "Scripts", "genes.hg19.ensembl.rds")

Loading data

dir_dest1 <- "/home/katarina/MyProjects/HNSCC/01-Exploratory_analysis_and_differential_expression"
dir_dest2 <- "/home/katarina/MyProjects/HNSCC/02-Regulation_targets"

## 01
# mRNA
mRNA_res <- readRDS(file.path(dir_dest1,"outputs/RDS/mRNA_res.rds"))
# miR
mir_res <- readRDS(file.path(dir_dest1,"outputs/RDS/mir_res.rds"))
# dnam
dnam_res_cgi <- readRDS(file.path(dir_dest1,"outputs/RDS/dnam_res_cgi.rds"))


## 02
# miR-mRNA
targ_mir_mRNA <- readRDS(file.path(dir_dest2,"outputs/RDS/targ_mir_mRNA.rds"))
cor_mir <- readRDS(file.path(dir_dest2,"outputs/RDS/cor_mir.rds"))
# dnam-mRNA
targ_dnam_mRNA <- readRDS(file.path(dir_dest2,"outputs/RDS/targ_dnam_mRNA.rds"))

Integrated table

In this chapter we build the integrated table that will contain multiple information from different data sets.

Firstly, filtering mRNA results to get only significantly DE genes.

mRNA_de <- filter(as.data.frame(mRNA_res),padj < 0.05)

Venn

simple_tb <- 
  data.frame(genes=rownames(mRNA_de)) %>%
  mutate(mir=dplyr::case_when(
    is.element(genes,targ_mir_mRNA$target_ensembl) ~ 1, TRUE ~ 0)) %>%
  mutate(dnam=dplyr::case_when(
    is.element(genes, targ_dnam_mRNA$ensembl) ~ 1, TRUE ~ 0))

# table of genes under regulation
table(simple_tb [,c("mir","dnam")])
   dnam
mir    0    1
  0 1129  776
  1  356  732
venn::venn(x =list(simple_tb[simple_tb$dnam ==1,"genes"],
             simple_tb[simple_tb$mir ==1,"genes"]), 
     zcolor = "style",
     snames = c("DNA methylated","microRNA"))

GSEA analysis on simple_tb

To explore the influence of different types of regulation we preform gsea on crude groups of genes where the genes are presneted in the venn. From the gostplot there are not many terms associated with genes that are ONLY under DNA methylation regulation (Only muscle contraction -REAC). In the intersection part there are terms that are involved in cell cycle regulation, regulation of transcription, .. Genes under mir regulation have many terms involved with the immune system, also some terms involved with cell mobility (cell-cell adhesion, cell migration, collagen degradation). The rest that are not under dnam or mir regulation have terms involved in muscle contractions and some immunological pathways. TF database added later, comment: In all groups there are many hits with TF.

# Building multiple queries
query_ls <- 
  list(dnam = filter(simple_tb, mir == 0 & dnam == 1 )$genes,
       mir = filter(simple_tb, mir == 1 & dnam == 0 )$genes,
       intersection = filter(simple_tb, mir == 1 & dnam == 1 )$genes,
       rest = filter(simple_tb, mir == 0 & dnam == 0 )$genes)

# Sources
GSEA_SOURCES <- c("GO:BP","CORUM","KEGG","REAC","WP","MIRNA", "TF")

gost <-
  gost(query = query_ls,
       organism= "hsapiens",
       exclude_iea=TRUE,
       domain_scope="annotated",
       ordered_query=F,
       sources=GSEA_SOURCES)

# Plot and table of significant results
gostplot(gost, capped = T, interactive = T)
Warning message:
`gather_()` was deprecated in tidyr 1.2.0.
Please use `gather()` instead.
This warning is displayed once every 8 hours.
Call `lifecycle::last_lifecycle_warnings()` to see where this warning was generated. 

Regulation table - integrated

Building a complete and comprehensive table with results of DE and DM of the transcriptomic (mRNA), small-RNA transcriptomic (mir) and DNA methylation (CpG islands) to have all significant data in one data frame. The comprehensive table will contain all mir mRNA and dnam mRNA pairs. ! add colnames!

# this steps for this are described in the script
integ_df <-
  integrateOmicsData(mrna_res_obj = mRNA_res,
                   mir_res_obj = mir_res,
                   dnam_res_obj = dnam_res_cgi,
                   mir_targets_cor = cor_mir,
                   genes_file = genes_dir)

head(integ_df)
message(paste0("Dimensions of integrated tbl: ", dim(integ_df)[1]))
Dimensions of integrated tbl: 4607
# Summary statistics
summary(integ_df)
     gene              symbol            gene_mean        
 Length:4607        Length:4607        Min.   :     2.07  
 Class :character   Class :character   1st Qu.:    50.97  
 Mode  :character   Mode  :character   Median :   263.10  
                                       Mean   :  1262.56  
                                       3rd Qu.:   876.42  
                                       Max.   :174035.04  
                                                          
    gene_FC          gene_pval           gene_pajd       
 Min.   :-7.3216   Min.   :0.000e+00   Min.   :0.000000  
 1st Qu.:-2.6883   1st Qu.:9.355e-05   1st Qu.:0.002654  
 Median :-1.3979   Median :9.092e-04   Median :0.012951  
 Mean   :-0.4427   Mean   :1.776e-03   Mean   :0.016942  
 3rd Qu.: 1.8978   3rd Qu.:3.027e-03   3rd Qu.:0.028972  
 Max.   : 6.9477   Max.   :6.988e-03   Max.   :0.049982  
                                                         
     mir                mir_r           mir_r_pval    
 Length:4607        Min.   :-0.9505   Min.   :0.0000  
 Class :character   1st Qu.:-0.4725   1st Qu.:0.0269  
 Mode  :character   Median : 0.0385   Median :0.1098  
                    Mean   : 0.0021   Mean   :0.2098  
                    3rd Qu.: 0.4560   3rd Qu.:0.3064  
                    Max.   : 0.9341   Max.   :1.0000  
                    NA's   :1929      NA's   :1929    
    mir_mean            mir_FC           mir_pval     
 Min.   :    2.77   Min.   :-4.1993   Min.   :0.0000  
 1st Qu.:   95.31   1st Qu.:-1.1996   1st Qu.:0.0001  
 Median :  392.78   Median : 1.3351   Median :0.0005  
 Mean   : 3165.96   Mean   : 0.8145   Mean   :0.0030  
 3rd Qu.: 1232.71   3rd Qu.: 2.4050   3rd Qu.:0.0061  
 Max.   :75885.30   Max.   : 5.2725   Max.   :0.0100  
 NA's   :1929       NA's   :1929      NA's   :1929    
    mir_padj        dnam_quot         dnam_pval     
 Min.   :0.0000   Min.   :-2.6695   Min.   :0.0000  
 1st Qu.:0.0022   1st Qu.:-0.3642   1st Qu.:0.0103  
 Median :0.0053   Median :-0.1369   Median :0.0376  
 Mean   :0.0156   Mean   :-0.0210   Mean   :0.0727  
 3rd Qu.:0.0314   3rd Qu.: 0.1289   3rd Qu.:0.0857  
 Max.   :0.0448   Max.   : 3.9967   Max.   :0.9481  
 NA's   :1929     NA's   :2342      NA's   :2342    
   dnam_padj      dnam_num_sites   dnam_condensed_ranges
 Min.   :0.0000   Min.   : 1.000   Length:4607          
 1st Qu.:0.0299   1st Qu.: 5.000   Class :character     
 Median :0.0693   Median : 7.000   Mode  :character     
 Mean   :0.0956   Mean   : 7.941                        
 3rd Qu.:0.1171   3rd Qu.:10.000                        
 Max.   :0.9492   Max.   :44.000                        
 NA's   :2342     NA's   :2342                          

Subseting integrated table

Here we want to make a table that has only one row per mRNA so that we can explore the influence of DE mir and dnam that are putative regulators of said mRNA. For multiple mir regulators we choose the best correlating one. For multiple dm cgi’s involved in regulating an mRNA we choose the one with the “best” (larger absolute value) fold change.

reg_df <-
  integ_df %>%
  # Group by gene to compare their regulators
  group_by(gene) %>%
  # Storing the best correlating mir into best_cor column
  # NA is for those that are not under mir regulation
  mutate(best_cor=ifelse(!is.na(mir_r), mir[which.max(abs(mir_r))], NA)) %>%
  # filtering out mirs that are not the best putative regulators
  dplyr::filter(is.na(mir) | mir == best_cor)  %>%
  # Storing the cgi with max abs value in best_cgi
  mutate(best_cgi= ifelse(!is.na(dnam_quot),                                 dnam_condensed_ranges[which.max(abs(dnam_quot))],
                                 NA)) %>%
  # Filtering out cgi that are not the best
  dplyr::filter(is.na(dnam_condensed_ranges) |
                  dnam_condensed_ranges == best_cgi) %>%
  # Dropping uneeded columns. This info is already in mir and dnam ranges
  dplyr::select(-best_cor, -best_cgi) %>%
  ungroup()

reg_df

Clustering

Using two unsupervised clustering methods SOM and kmeans to explore clusters of genes under different combination of regulations. Features are fold changes of mRNA and mir data and quotient of beta intensity value for dna methylation. We hypothesized that groups with mRNA FC values will be opposite of mir and dnam regulators which would suggest that those groups are under regulation of mir and/or dnam.

kmeans

K means clusters mRNA genes into k number of clusters in which each mRNA belongs to the cluster with the nearest mean (or cluster centroid). For more details look at the lecture materials from pmf machine learning.

# Prepping kmeans table
k_tb <- data.frame(row.names = reg_df$gene,
                   dplyr::select(reg_df,
                                 gene_FC,
                                 mir_FC,
                                 dnam_quot))

hist(k_tb$dnam_quot)

# Scaling (standardization - x-mean/sd)
# k_tb <- scale(k_tb) %>%
#   as.data.frame()


#k_tb$dnam_quot <- scale(k_tb$dnam_quot)
# Doubling values so that the colors are more intense
k_tb$dnam_quot <- k_tb$dnam_quot*2

hist(k_tb$dnam_quot)


# All NA values are 0
k_tb[is.na(k_tb)] <- 0
kmeansHeatmap(k_tb, clusters= 10:14, nstart = 60)

Testing the plotting function

Session Info

sessionInfo()
LS0tCnRpdGxlOiAiMDMtSW50ZWdyYXRpdmVfYW5hbHlzaXMiCm91dHB1dDogaHRtbF9ub3RlYm9vawotLS0KCiMgRGVzY3JpcHRpb24KCkluIHRoaXMgbm90ZWJvb2sgYW4gaW50ZWdyYXRlZCBhbmFseXNpcyBpcyBwcmVmb3JtZWQuClBhaXIgaW50ZXJhY3Rpb24gZGF0YSBvZiBtaVIgLSB0YXJnZXQobVJOQSkgYW5kIEROQW0gLSB0YXJnZXQobVJOQSkgaXMgYW4gb3V0cHV0IGZyb20gbm90ZWJvb2sgMDItUmVndWxhdGlvbl90YXJnZXRzLgpJbnRlZ3JhdGl2ZSBhbmFseXNpcyBpcyBnb2ludCBnbyBiZSBmb2N1c2VkIG9uIG1STkEgc28gYSB0YWJsZSB3aXRoIHNpZ25pZmljYW50bHkgREUgYW5kIG9uZSBvZiBpdHMgcmVndWxhdG9yLiBTaW5jZSB0aGVyZSBhcmUgc29tZSBnZW5lcyB0aGF0IGhhdmUgbXVsdGlwbGUgcmVndWxhdG9ycyBtaXLigJlzIHdpdGggdGhlIGJlc3QgY29ycmVsYXRpb24gd2lsbCBiZSBzZWxlY3RlZCBhcyBhIHJlZ3VsYXRvci4gRm9yIEROQW0gISEhIGdldCBiYWNrIHRvIHRoaXMKVG8gZXhwbG9yZSB0aGUgaW5mbHVlbmNlIG9mIG1pUiBhbmQgRE5BbSBvbiBtUk5BIGV4cHJlc3Npb24gd2Ugd2lsbCBwcmVmb3JtIEdTRUEgb24gZ3JvdXBzIG9mIGdlbmVzIHRoYXQgYXJlIHVuZGVyIHJlZ3VsYXRpb24gb2YgRE5BbSwgbWlyIG9yIGJvdGguIE5leHQsIHdlIHdpbGwgbWFrZSBhbiB1bnN1cGVydmlzZWQgY2x1c3RlcmluZyBvbiBnZW5lcyB3aXRoIEZDIGZlYXR1cmVzIHRvIGZpbmQgcGF0dGVybnMgaW4gZ2VuZSBleHByZXNzaW9ucy4gKE9WTyBJU1RPIFBPQk9MSsWgQVRJKQoKIyBMaWJyYXJpZXMKYGBge3J9CmxpYnJhcnkodmVubikKbGlicmFyeShkcGx5cikKbGlicmFyeShHZW5vbWljUmFuZ2VzKQpsaWJyYXJ5KGdwcm9maWxlcjIpCmxpYnJhcnkoREVTZXEyKQpsaWJyYXJ5KHRpYmJsZSkKbGlicmFyeShrb2hvbmVuKQpsaWJyYXJ5KHJwcm9qcm9vdCkKCgoKIyBzb3VyY2UoZmlsZSA9IGZpbGUucGF0aChnZXR3ZCgpLCAic2NyaXB0cyIsICJpZE1hcC5SIikpCiMgc291cmNlKGZpbGUgPSBmaWxlLnBhdGgoZ2V0d2QoKSwgInNjcmlwdHMiLCAiaW50ZWdyYXRlT21pY3NEYXRhLlIiKSkKIyBzb3VyY2UoZmlsZSA9IGZpbGUucGF0aChnZXR3ZCgpLCAic2NyaXB0cyIsICJrbWVhbnNIZWF0bWFwLlIiKSkKCmdlbmVzX2RpciA8LSBmaWxlLnBhdGgoZmluZF9yc3R1ZGlvX3Jvb3RfZmlsZSgpLCAiU2NyaXB0cyIsICJnZW5lcy5oZzE5LmVuc2VtYmwucmRzIikKYGBgCgoKIyBMb2FkaW5nIGRhdGEKYGBge3IgTGlicmFyaWVzLCBtZXNzYWdlPUZBTFNFfQpkaXJfZGVzdDEgPC0gIi9ob21lL2thdGFyaW5hL015UHJvamVjdHMvSE5TQ0MvMDEtRXhwbG9yYXRvcnlfYW5hbHlzaXNfYW5kX2RpZmZlcmVudGlhbF9leHByZXNzaW9uIgpkaXJfZGVzdDIgPC0gIi9ob21lL2thdGFyaW5hL015UHJvamVjdHMvSE5TQ0MvMDItUmVndWxhdGlvbl90YXJnZXRzIgoKIyMgMDEKIyBtUk5BCm1STkFfcmVzIDwtIHJlYWRSRFMoZmlsZS5wYXRoKGRpcl9kZXN0MSwib3V0cHV0cy9SRFMvbVJOQV9yZXMucmRzIikpCiMgbWlSCm1pcl9yZXMgPC0gcmVhZFJEUyhmaWxlLnBhdGgoZGlyX2Rlc3QxLCJvdXRwdXRzL1JEUy9taXJfcmVzLnJkcyIpKQojIGRuYW0KZG5hbV9yZXNfY2dpIDwtIHJlYWRSRFMoZmlsZS5wYXRoKGRpcl9kZXN0MSwib3V0cHV0cy9SRFMvZG5hbV9yZXNfY2dpLnJkcyIpKQoKCiMjIDAyCiMgbWlSLW1STkEKdGFyZ19taXJfbVJOQSA8LSByZWFkUkRTKGZpbGUucGF0aChkaXJfZGVzdDIsIm91dHB1dHMvUkRTL3RhcmdfbWlyX21STkEucmRzIikpCmNvcl9taXIgPC0gcmVhZFJEUyhmaWxlLnBhdGgoZGlyX2Rlc3QyLCJvdXRwdXRzL1JEUy9jb3JfbWlyLnJkcyIpKQojIGRuYW0tbVJOQQp0YXJnX2RuYW1fbVJOQSA8LSByZWFkUkRTKGZpbGUucGF0aChkaXJfZGVzdDIsIm91dHB1dHMvUkRTL3RhcmdfZG5hbV9tUk5BLnJkcyIpKQpgYGAKCgojIEludGVncmF0ZWQgdGFibGUKSW4gdGhpcyBjaGFwdGVyIHdlIGJ1aWxkIHRoZSBpbnRlZ3JhdGVkIHRhYmxlIHRoYXQgd2lsbCBjb250YWluIG11bHRpcGxlIGluZm9ybWF0aW9uIGZyb20gZGlmZmVyZW50IGRhdGEgc2V0cy4KCkZpcnN0bHksIGZpbHRlcmluZyBtUk5BIHJlc3VsdHMgdG8gZ2V0IG9ubHkgc2lnbmlmaWNhbnRseSBERSBnZW5lcy4KYGBge3J9Cm1STkFfZGUgPC0gZmlsdGVyKGFzLmRhdGEuZnJhbWUobVJOQV9yZXMpLHBhZGogPCAwLjA1KQpgYGAKCiMgVmVubgpgYGB7cn0Kc2ltcGxlX3RiIDwtIAogIGRhdGEuZnJhbWUoZ2VuZXM9cm93bmFtZXMobVJOQV9kZSkpICU+JQogIG11dGF0ZShtaXI9ZHBseXI6OmNhc2Vfd2hlbigKICAgIGlzLmVsZW1lbnQoZ2VuZXMsdGFyZ19taXJfbVJOQSR0YXJnZXRfZW5zZW1ibCkgfiAxLCBUUlVFIH4gMCkpICU+JQogIG11dGF0ZShkbmFtPWRwbHlyOjpjYXNlX3doZW4oCiAgICBpcy5lbGVtZW50KGdlbmVzLCB0YXJnX2RuYW1fbVJOQSRlbnNlbWJsKSB+IDEsIFRSVUUgfiAwKSkKCiMgdGFibGUgb2YgZ2VuZXMgdW5kZXIgcmVndWxhdGlvbgp0YWJsZShzaW1wbGVfdGIgWyxjKCJtaXIiLCJkbmFtIildKQoKCgp2ZW5uOjp2ZW5uKHggPWxpc3Qoc2ltcGxlX3RiW3NpbXBsZV90YiRkbmFtID09MSwiZ2VuZXMiXSwKICAgICAgICAgICAgIHNpbXBsZV90YltzaW1wbGVfdGIkbWlyID09MSwiZ2VuZXMiXSksIAogICAgIHpjb2xvciA9ICJzdHlsZSIsCiAgICAgc25hbWVzID0gYygiRE5BIG1ldGh5bGF0ZWQiLCJtaWNyb1JOQSIpKQpgYGAKIyMgR1NFQSBhbmFseXNpcyBvbiBzaW1wbGVfdGIKVG8gZXhwbG9yZSB0aGUgaW5mbHVlbmNlIG9mIGRpZmZlcmVudCB0eXBlcyBvZiByZWd1bGF0aW9uIHdlIHByZWZvcm0gZ3NlYSBvbiBjcnVkZSBncm91cHMgb2YgZ2VuZXMgd2hlcmUgdGhlIGdlbmVzIGFyZSBwcmVzbmV0ZWQgaW4gdGhlIHZlbm4uCkZyb20gdGhlIGdvc3RwbG90IHRoZXJlIGFyZSBub3QgbWFueSB0ZXJtcyBhc3NvY2lhdGVkIHdpdGggZ2VuZXMgdGhhdCBhcmUgT05MWSB1bmRlciBETkEgbWV0aHlsYXRpb24gcmVndWxhdGlvbiAoT25seSBtdXNjbGUgY29udHJhY3Rpb24gLVJFQUMpLiBJbiB0aGUgaW50ZXJzZWN0aW9uIHBhcnQgdGhlcmUgYXJlIHRlcm1zIHRoYXQgYXJlIGludm9sdmVkIGluIGNlbGwgY3ljbGUgcmVndWxhdGlvbiwgcmVndWxhdGlvbiBvZiB0cmFuc2NyaXB0aW9uLCAuLiBHZW5lcyB1bmRlciBtaXIgcmVndWxhdGlvbiBoYXZlIG1hbnkgdGVybXMgaW52b2x2ZWQgd2l0aCB0aGUgaW1tdW5lIHN5c3RlbSwgYWxzbyBzb21lIHRlcm1zIGludm9sdmVkIHdpdGggY2VsbCBtb2JpbGl0eSAoY2VsbC1jZWxsIGFkaGVzaW9uLCBjZWxsIG1pZ3JhdGlvbiwgY29sbGFnZW4gZGVncmFkYXRpb24pLiBUaGUgcmVzdCB0aGF0IGFyZSBub3QgdW5kZXIgZG5hbSBvciBtaXIgcmVndWxhdGlvbiBoYXZlIHRlcm1zIGludm9sdmVkIGluIG11c2NsZSBjb250cmFjdGlvbnMgYW5kIHNvbWUgaW1tdW5vbG9naWNhbCBwYXRod2F5cy4gVEYgZGF0YWJhc2UgYWRkZWQgbGF0ZXIsIGNvbW1lbnQ6IEluIGFsbCBncm91cHMgdGhlcmUgYXJlIG1hbnkgaGl0cyB3aXRoIFRGLgoKYGBge3J9CiMgQnVpbGRpbmcgbXVsdGlwbGUgcXVlcmllcwpxdWVyeV9scyA8LSAKICBsaXN0KGRuYW0gPSBmaWx0ZXIoc2ltcGxlX3RiLCBtaXIgPT0gMCAmIGRuYW0gPT0gMSApJGdlbmVzLAogICAgICAgbWlyID0gZmlsdGVyKHNpbXBsZV90YiwgbWlyID09IDEgJiBkbmFtID09IDAgKSRnZW5lcywKICAgICAgIGludGVyc2VjdGlvbiA9IGZpbHRlcihzaW1wbGVfdGIsIG1pciA9PSAxICYgZG5hbSA9PSAxICkkZ2VuZXMsCiAgICAgICByZXN0ID0gZmlsdGVyKHNpbXBsZV90YiwgbWlyID09IDAgJiBkbmFtID09IDAgKSRnZW5lcykKCiMgU291cmNlcwpHU0VBX1NPVVJDRVMgPC0gYygiR086QlAiLCJDT1JVTSIsIktFR0ciLCJSRUFDIiwiV1AiLCJNSVJOQSIsICJURiIpCgpnb3N0IDwtCiAgZ29zdChxdWVyeSA9IHF1ZXJ5X2xzLAogICAgICAgb3JnYW5pc209ICJoc2FwaWVucyIsCiAgICAgICBleGNsdWRlX2llYT1UUlVFLAogICAgICAgZG9tYWluX3Njb3BlPSJhbm5vdGF0ZWQiLAogICAgICAgb3JkZXJlZF9xdWVyeT1GLAogICAgICAgc291cmNlcz1HU0VBX1NPVVJDRVMpCgojIFBsb3QgYW5kIHRhYmxlIG9mIHNpZ25pZmljYW50IHJlc3VsdHMKZ29zdHBsb3QoZ29zdCwgY2FwcGVkID0gVCwgaW50ZXJhY3RpdmUgPSBUKQpgYGAKCiMgUmVndWxhdGlvbiB0YWJsZSAtIGludGVncmF0ZWQKQnVpbGRpbmcgYSBjb21wbGV0ZSBhbmQgY29tcHJlaGVuc2l2ZSB0YWJsZSB3aXRoIHJlc3VsdHMgb2YgREUgYW5kIERNIG9mIHRoZSB0cmFuc2NyaXB0b21pYyAobVJOQSksIHNtYWxsLVJOQSB0cmFuc2NyaXB0b21pYyAobWlyKSBhbmQgRE5BIG1ldGh5bGF0aW9uIChDcEcgaXNsYW5kcykgdG8gaGF2ZSBhbGwgc2lnbmlmaWNhbnQgZGF0YSBpbiBvbmUgZGF0YSBmcmFtZS4gVGhlIGNvbXByZWhlbnNpdmUgdGFibGUgd2lsbCBjb250YWluIGFsbCBtaXIgbVJOQSBhbmQgZG5hbSBtUk5BIHBhaXJzLiAhIGFkZCBjb2xuYW1lcyEKCmBgYHtyfQojIHRoaXMgc3RlcHMgZm9yIHRoaXMgYXJlIGRlc2NyaWJlZCBpbiB0aGUgc2NyaXB0CmludGVnX2RmIDwtCiAgaW50ZWdyYXRlT21pY3NEYXRhKG1ybmFfcmVzX29iaiA9IG1STkFfcmVzLAogICAgICAgICAgICAgICAgICAgbWlyX3Jlc19vYmogPSBtaXJfcmVzLAogICAgICAgICAgICAgICAgICAgZG5hbV9yZXNfb2JqID0gZG5hbV9yZXNfY2dpLAogICAgICAgICAgICAgICAgICAgbWlyX3RhcmdldHNfY29yID0gY29yX21pciwKICAgICAgICAgICAgICAgICAgIGdlbmVzX2ZpbGUgPSBnZW5lc19kaXIpCgpoZWFkKGludGVnX2RmKQptZXNzYWdlKHBhc3RlMCgiRGltZW5zaW9ucyBvZiBpbnRlZ3JhdGVkIHRibDogIiwgZGltKGludGVnX2RmKVsxXSkpCiMgU3VtbWFyeSBzdGF0aXN0aWNzCnN1bW1hcnkoaW50ZWdfZGYpCmBgYAoKIyMgU3Vic2V0aW5nIGludGVncmF0ZWQgdGFibGUKSGVyZSB3ZSB3YW50IHRvIG1ha2UgYSB0YWJsZSB0aGF0IGhhcyBvbmx5IG9uZSByb3cgcGVyIG1STkEgc28gdGhhdCB3ZSBjYW4gZXhwbG9yZSB0aGUgaW5mbHVlbmNlIG9mIERFIG1pciBhbmQgZG5hbSB0aGF0IGFyZSBwdXRhdGl2ZSByZWd1bGF0b3JzIG9mIHNhaWQgbVJOQS4gRm9yIG11bHRpcGxlIG1pciByZWd1bGF0b3JzIHdlIGNob29zZSB0aGUgYmVzdCBjb3JyZWxhdGluZyBvbmUuIEZvciBtdWx0aXBsZSBkbSBjZ2nigJlzIGludm9sdmVkIGluIHJlZ3VsYXRpbmcgYW4gbVJOQSB3ZSBjaG9vc2UgdGhlIG9uZSB3aXRoIHRoZSDigJxiZXN04oCdIChsYXJnZXIgYWJzb2x1dGUgdmFsdWUpIGZvbGQgY2hhbmdlLgpgYGB7cn0KcmVnX2RmIDwtCiAgaW50ZWdfZGYgJT4lCiAgIyBHcm91cCBieSBnZW5lIHRvIGNvbXBhcmUgdGhlaXIgcmVndWxhdG9ycwogIGdyb3VwX2J5KGdlbmUpICU+JQogICMgU3RvcmluZyB0aGUgYmVzdCBjb3JyZWxhdGluZyBtaXIgaW50byBiZXN0X2NvciBjb2x1bW4KICAjIE5BIGlzIGZvciB0aG9zZSB0aGF0IGFyZSBub3QgdW5kZXIgbWlyIHJlZ3VsYXRpb24KICBtdXRhdGUoYmVzdF9jb3I9aWZlbHNlKCFpcy5uYShtaXJfciksIG1pclt3aGljaC5tYXgoYWJzKG1pcl9yKSldLCBOQSkpICU+JQogICMgZmlsdGVyaW5nIG91dCBtaXJzIHRoYXQgYXJlIG5vdCB0aGUgYmVzdCBwdXRhdGl2ZSByZWd1bGF0b3JzCiAgZHBseXI6OmZpbHRlcihpcy5uYShtaXIpIHwgbWlyID09IGJlc3RfY29yKSAgJT4lCiAgIyBTdG9yaW5nIHRoZSBjZ2kgd2l0aCBtYXggYWJzIHZhbHVlIGluIGJlc3RfY2dpCiAgbXV0YXRlKGJlc3RfY2dpPSBpZmVsc2UoIWlzLm5hKGRuYW1fcXVvdCksICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZG5hbV9jb25kZW5zZWRfcmFuZ2VzW3doaWNoLm1heChhYnMoZG5hbV9xdW90KSldLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOQSkpICU+JQogICMgRmlsdGVyaW5nIG91dCBjZ2kgdGhhdCBhcmUgbm90IHRoZSBiZXN0CiAgZHBseXI6OmZpbHRlcihpcy5uYShkbmFtX2NvbmRlbnNlZF9yYW5nZXMpIHwKICAgICAgICAgICAgICAgICAgZG5hbV9jb25kZW5zZWRfcmFuZ2VzID09IGJlc3RfY2dpKSAlPiUKICAjIERyb3BwaW5nIHVuZWVkZWQgY29sdW1ucy4gVGhpcyBpbmZvIGlzIGFscmVhZHkgaW4gbWlyIGFuZCBkbmFtIHJhbmdlcwogIGRwbHlyOjpzZWxlY3QoLWJlc3RfY29yLCAtYmVzdF9jZ2kpICU+JQogIHVuZ3JvdXAoKQoKcmVnX2RmCmBgYAojIENsdXN0ZXJpbmcKVXNpbmcgdHdvIHVuc3VwZXJ2aXNlZCBjbHVzdGVyaW5nIG1ldGhvZHMgU09NIGFuZCBrbWVhbnMgdG8gZXhwbG9yZSBjbHVzdGVycyBvZiBnZW5lcyB1bmRlciBkaWZmZXJlbnQgY29tYmluYXRpb24gb2YgcmVndWxhdGlvbnMuIEZlYXR1cmVzIGFyZSBmb2xkIGNoYW5nZXMgb2YgbVJOQSBhbmQgbWlyIGRhdGEgYW5kIHF1b3RpZW50IG9mIGJldGEgaW50ZW5zaXR5IHZhbHVlIGZvciBkbmEgbWV0aHlsYXRpb24uIFdlIGh5cG90aGVzaXplZCB0aGF0IGdyb3VwcyB3aXRoIG1STkEgRkMgdmFsdWVzIHdpbGwgYmUgb3Bwb3NpdGUgb2YgbWlyIGFuZCBkbmFtIHJlZ3VsYXRvcnMgd2hpY2ggd291bGQgc3VnZ2VzdCB0aGF0IHRob3NlIGdyb3VwcyBhcmUgdW5kZXIgcmVndWxhdGlvbiBvZiBtaXIgYW5kL29yIGRuYW0uCgojIyAqKmttZWFucyoqCksgbWVhbnMgY2x1c3RlcnMgbVJOQSBnZW5lcyBpbnRvIGsgbnVtYmVyIG9mIGNsdXN0ZXJzIGluIHdoaWNoIGVhY2ggbVJOQSBiZWxvbmdzIHRvIHRoZSBjbHVzdGVyIHdpdGggdGhlIG5lYXJlc3QgbWVhbiAob3IgY2x1c3RlciBjZW50cm9pZCkuIEZvciBtb3JlIGRldGFpbHMgbG9vayBhdCB0aGUgbGVjdHVyZSBtYXRlcmlhbHMgZnJvbSBwbWYgbWFjaGluZSBsZWFybmluZy4KYGBge3J9CiMgUHJlcHBpbmcga21lYW5zIHRhYmxlCmtfdGIgPC0gZGF0YS5mcmFtZShyb3cubmFtZXMgPSByZWdfZGYkZ2VuZSwKICAgICAgICAgICAgICAgICAgIGRwbHlyOjpzZWxlY3QocmVnX2RmLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZW5lX0ZDLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtaXJfRkMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRuYW1fcXVvdCkpCgpoaXN0KGtfdGIkZG5hbV9xdW90KQojIFNjYWxpbmcgKHN0YW5kYXJkaXphdGlvbiAtIHgtbWVhbi9zZCkKIyBrX3RiIDwtIHNjYWxlKGtfdGIpICU+JQojICAgYXMuZGF0YS5mcmFtZSgpCgoKI2tfdGIkZG5hbV9xdW90IDwtIHNjYWxlKGtfdGIkZG5hbV9xdW90KQojIERvdWJsaW5nIHZhbHVlcyBzbyB0aGF0IHRoZSBjb2xvcnMgYXJlIG1vcmUgaW50ZW5zZQprX3RiJGRuYW1fcXVvdCA8LSBrX3RiJGRuYW1fcXVvdCoyCgpoaXN0KGtfdGIkZG5hbV9xdW90KQoKIyBBbGwgTkEgdmFsdWVzIGFyZSAwCmtfdGJbaXMubmEoa190YildIDwtIDAKYGBgCgoKYGBge3J9CmttZWFuc0hlYXRtYXAoa190YiwgY2x1c3RlcnM9IDEwOjE0LCBuc3RhcnQgPSA2MCkKYGBgCgpUZXN0aW5nIHRoZSBwbG90dGluZyBmdW5jdGlvbgpgYGB7cn0Ka21lYW5zX3RiIDwtIHJlYWRSRFMoImNsdXN0ZXJpbmcvMjAyMjA3MTJfMTMzMV9fMTJjbHVzdGVyc182MG5zdGFydC5yZHMiKQoKcGxvdEttZWFuc1BoZWF0bWFwKGttZWFuc190YikKYGBgCgoKIyBTZXNzaW9uIEluZm8KYGBge3IgU2Vzc2lvbiBpbmZvfQpzZXNzaW9uSW5mbygpCmBgYAo=